<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义slider组件</title>
    <style>
        .slider-box{
            border: 1px solid black;
            position: relative;
            height: 40px;
            width: 400px;
        }
        .slider-line{
            position: absolute;
            height: 6px;
            background-color: grey;
            left: 20px;
            top: 17px;
        }
        .slider-point{
            position: absolute;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: radial-gradient(yellow,red);
            top: 10px;
        }
    </style>
</head>
<body>
    <div id="app">
        输入音量值：<input v-model.number="vol">
        选择滑块滑过的颜色：<input type="color" v-model='slipedColor'>
        选择滑块的颜色：<input type="color" v-model='slipColor'>
        输入滑杆的长度：<input v-model.number="sliderWidth">
        <hr>
        <!--
            双向绑定
            v-model='vol' ==> :value='vol' @input='volchange' 
            v-model仅仅是一个语法糖，一个v-model相当于一个v-bind加上一个v-on；
            v-bind绑定value属性，v-on绑定input事件
        -->
        <!--
            自定义的组件可以使用v-model指令，按照v-model的工作原理：
            组件必须通过value的propos接收外界传值
            必须通过发射input事件向外界传值
        -->
        <slider v-model="vol" :sliped-color='slipedColor' :slip-color='slipColor' :slider-width='sliderWidth'></slider><!--不加:号相当于传递了字符串，加上相当于传递变量-->
    </div>
    <script src='vue.js'></script>
    <!--slider模版-->
    <script type="text/html" id="slider"><!--组件是可以设置属性的，属性会设置在根元素上，所以组件只能有一个根元素-->
        <div class="slider-box" :style='{width:sliderWidth+40+"px"}' @mousedown='mousedown' @mousemove='mousemove' @mouseup='mouseup'>
            <div class="slider-line" :style='lineStyle'></div>
            <div class="slider-point" :style='pointStyle'></div><!--style和class一般绑定对象-->
        </div>
    </script>
    <!--组件-->
    <script>
        Vue.component('slider',{
            template:'#slider',
            data:function(){
                return {
                    isdown:false/*记录鼠标是否按下*/
                }
            },
            props:['value','slipedColor','slipColor','sliderWidth'],
            computed:{/*把props得到的数据作为一个待处理的值时，使用computed修改*/
                pointStyle:function(){
                    var l = this.value*this.sliderWidth + 20 -10/*范围是0-360,加上左边距，减去小圆点的半径*/
                    l = l < 10 ? 10 : l   /*设定小圆点left范围10-370*/
                    l = l > this.sliderWidth+10 ? this.sliderWidth+10 : l
                    return {
                        left:l+'px' /*设置小圆点style的left的值*/
                    }
                },
                lineStyle:function(){
                    var percent = this.value * 100 + '%'
                    var bg = "linear-gradient(to right,"+this.slipedColor+","+this.slipedColor+" "+percent+","+this.slipColor+","+this.slipColor+" "+percent+")"
                    return {
                        width:this.sliderWidth + 'px',
                        background:bg
                    }
                }
            },
            methods:{
                mousedown(e){
                    var x = e.pageX - this.$el.offsetLeft /*this.$el获得当前组件的根元素，也验证了组件模板必须只有一个根标签*/
                    x =  x < 20 ? 20 : x /*将x的范围从0-400改为20-380*/
                    x = x > this.sliderWidth+20 ? this.sliderWidth+20 : x
                    var r = (x - 20)/360 /*传给父组件的参数必须是一个0-1的值，将x的范围20-380转变为0-1*/
                    this.$emit('input',r.toFixed(2))
                    this.isdown = true /*鼠标按下时置为true*/
                },
                mousemove(e){
                    if(this.isdown){ /*移动过程中重新计算vol值并发射给父组件*/
                        var x = e.pageX - this.$el.offsetLeft 
                        x = x < 20 ? 20 : x
                        x = x > this.sliderWidth+20 ? this.sliderWidth+20 : x
                        var r = (x - 20) / this.sliderWidth
                        this.$emit('input',r.toFixed(2))
                    }
                },
                mouseup(e){
                    this.isdown = false /*鼠标抬起时置为false*/
                }
            },
            mounted:function(){
                window.addEventListener('mousemove',this.mousemove)
                window.addEventListener('mouseup',this.mouseup)
            }
        })
        new Vue({
            el:'#app',
            data:{
                vol:0.5,
                slipedColor:'#ff0000',
                slipColor:'#00ff00',
                sliderWidth:360,
            },
            methods:{
                // volchange(e){/*监听子组件发射的事件的回调函数*/
                //     this.vol = e /*改变父组件vol的值为子组件传递的参数*/
                // }
            }
        })
    </script>
</body>
</html>